/**
 * 网络请求的工具
 * 原有的fetch不支持中断请求和请求超时
 * 通过Promise.race 实现请求超时处理以及手动中断请求
 */
import React from 'react';
import {
    AsyncStorage,
    Platform,
    NetInfo,
    Keyboard,
} from 'react-native';
let lastNetStatus="offline"
let NetUtil={
    isDataValid: function (data="") {
        if (data != null) {
            data=data.toString()
            if(data != "" && data != "undefined"&&data!="null"){
               return true; 
            }  
        }
        return false;
        
    },
    removeStorage:function(key){
        AsyncStorage.removeItem(key.toLowerCase())
            .then(()=> {})
            .catch((error) => {})
            .done();
    },
    clearuserInfo:function(){
        this.removeStorage("token");
        this.removeStorage("phone");
    },
	/**
     * post请求
     * url : 请求地址
     * data : 参数(Json对象)
     * callback : 回调函数
     * */
     fetch_request(url,params="",headers={}) {
        let header = {
            'Accept': 'application/json',
            'Content-Type': 'application/json;charset=UTF-8',
             "from":"fdm"
        }
        
        let request={}
        if (params==null||params == '') {
            request={method: "GET", headers: Object.assign(header,headers)}
        } else {
            request={method: "POST", headers: Object.assign(header,headers), body: params}
        }
        let promise = new Promise((resolve, reject) => {
            NetInfo.isConnected.fetch().then((isConnected) => {
                if(!isConnected){
                    reject("无网络")
                    return;
                }
                fetch(url, request)
                    .then(res => {
                        if (res.status !=200) {
                          //this.reportHttpLog(url,res.status,res.statusText)
                        }
                        return res;
                    })
                    .then(response => response.text())
                    .then(responseData => resolve(responseData))
                    .then(err => reject(err))
                    .catch((err)=>reject(err))
            });
        })
        return this.warp_fetch(promise);
    },


    /**
     * 创建两个promise对象，一个负责网络请求，另一个负责计时，如果超过指定时间，就会先回调计时的promise，代表网络超时。
     * @param {Promise} fetch_promise    fetch请求返回的Promise
     * @param {number} [timeout=120000]   单位：毫秒，这里设置默认超时时间为2分钟
     * @return 返回Promise
     */
     warp_fetch(fetch_promise, timeout = 120000) {
        let timeout_fn = null;
        let abort = null;
        //创建一个超时promise
        let timeout_promise = new Promise(function (resolve, reject) {
            timeout_fn = function () {
                reject('网络请求超时');
            };
        });
        //创建一个终止promise
        let abort_promise = new Promise(function (resolve, reject) {
            abort = function () {
                reject('请求终止');
            };
        });
        //竞赛
        let abortable_promise = Promise.race([
            fetch_promise,
            timeout_promise,
            abort_promise,
        ]);
        //计时
        setTimeout(timeout_fn, timeout);
        //终止
        abortable_promise.abort = abort;
        return abortable_promise;
    },
    requestForm:function(url, data={}, successCallBack, errCallBack) {
        var request = new XMLHttpRequest();
        const formData = new FormData();
        if(data&&Object.keys(data).length>0){
            let ObjKeys=Object.keys(data);
            ObjKeys&&Array.isArray(ObjKeys)&&ObjKeys.map((key)=>{
                formData.append(key,data[key]);
            })
        }
        this.request(url, formData, successCallBack, errCallBack,{"Content-Type":"multipart/form-data;charset=utf-8"})
    },
    request:function (url, data="", successCallBack, errCallBack,header={}) {
        //判断url是否是正确
        if(!this.isDataValid(url)||url.indexOf("undefined")==0||url.indexOf("null")==0){
            errCallBack&&typeof(errCallBack)=="function"&&errCallBack("url请求地址错误");
            return null;
        }
        console.log("url==="+url)
		let promise=this.fetch_request(url,data,header)
		promise.then((responseText)=>{
            try{
                this.doResult(responseText,successCallBack, errCallBack) 
            }catch(err){//处理返回内容是html格式解析错误的情况
                this.SyntaxError(url,responseText,err,errCallBack);
            }
		}).catch((err)=>{
            this.SyntaxError(url,err,err,errCallBack);
		})
		return promise;
    },
     /*
    * 统一处理返回结果
    */
    doResult:function(responseText,successCallBack, errCallBack){
       if(!responseText){
            return;
       }
         console.log("responseText=@@=="+responseText)
        if(responseText=="Not Found"){
            errCallBack&&typeof(errCallBack)=="function"&&errCallBack("服务器访问失败，请稍后重试");
            return;
        }
        if(responseText.indexOf("503 Service Unavailable")>=0){
             errCallBack&&typeof(errCallBack)=="function"&&errCallBack("服务器繁忙，请稍后重试");
             return;
        }
        var responseData=eval("(" + responseText + ")");
        if (responseData.code >= 0) {
            successCallBack&&typeof(successCallBack)=="function"&&successCallBack(responseData.data,responseData.code,responseData.msg);
        } else if(responseData.code==-2){
            //token验证失败
            this.clearuserInfo();
            errCallBack&&typeof(errCallBack)=="function"&&errCallBack("登录失效,请重新登录");
            
        }else {
            if(this.isDataValid(responseData.msg)){
                errCallBack&&typeof(errCallBack)=="function"&&errCallBack(responseData.msg,responseData.data,responseData.code);
            }else{
                errCallBack&&typeof(errCallBack)=="function"&&errCallBack("数据解析错误");
            }
           
        }
    },
    SyntaxError:function(url,responseText,err,errCallBack) {
        if(err&&err.toString()=="请求终止"){
            return;
        }
        if(err&&err.toString()=="无网络"){
            errCallBack&&typeof(errCallBack)=="function"&&errCallBack("没有网络连接");
            return;
        }
        if(err&&err.toString().includes("TypeError: Network request failed")){
            errCallBack&&typeof(errCallBack)=="function"&&errCallBack('网络请求失败');
            //this.reportHttpLog(url,-200,responseText,err)  
            return;
        }
        if(err&&(err.toString().indexOf("SyntaxError")>=0)||(err.toString().indexOf("Unexpected token '<'")>=0)){
            errCallBack&&typeof(errCallBack)=="function"&&errCallBack('服务器解析错误');
        }else if(err&&err.toString().includes("请求超时")){
            errCallBack&&typeof(errCallBack)=="function"&&errCallBack(err); 
        }else{
            errCallBack&&typeof(errCallBack)=="function"&&errCallBack('服务器请求错误'+err); 
        }
       // this.reportHttpLog(url,200,responseText,err)  
        
    },

     getStorage:function(key, callback){
        AsyncStorage.getItem(key.toLowerCase())
            .then((value) => {
                callback&&typeof(callback)=="function"&&callback(value);
            })
            .catch((error) => {
                callback&&typeof(callback)=="function"&&callback(null)
            })
            .done();
    },
}
module.exports =NetUtil